#include "usart_thread.h"
#include "usart.h"
#include "malloc.h"


/*******串口1************************/
#define UART1_DMA_RX_BUF_SIZE 50
uint8_t UART1_DMA_RX_BUF[UART1_DMA_RX_BUF_SIZE]; //串口DMA接收缓存

#define UART1_DMA_TX_BUF_SIZE 50
uint8_t UART1_DMA_TX_BUF[UART1_DMA_TX_BUF_SIZE]; //串口DMA接收缓存





void Uart1_SendTask(void *p_arg);// 任务函数
void USART1_SendRecSignal(void);
void USART1_AwaitRecSignal(void);
bool USART1_DMASendData(SerialData *data);




rt_mq_t Uart1_Receive_mq = RT_NULL;         //串口2接收信号量
rt_sem_t Uart1_SendComplete_sem = RT_NULL;    //串口2发送完成中断信号量


rt_mq_t  Usart1_send_mq=RT_NULL;         //串口2发送消息队列

extern Mallco_dev mallco_dev; //内存管理器

__weak void Usart1_RxCallback(uint8_t *data, uint8_t Size)
{
}
/*************************
 * 功能：接收线程入口函数
*************************/
void Usart1_Receive_thread_entry(void *paremeter)
{
    SerialData data;;
    Uart1_Receive_mq=rt_mq_create("uart1_receive_mq",      //消息队列名称
	                               sizeof(SerialData),                   //消息最大长度
	                               10,                   //队列长度
	                               RT_IPC_FLAG_FIFO      //等待的方式
	                               );
	HAL_UARTEx_ReceiveToIdle_DMA(&huart1,UART1_DMA_RX_BUF,UART1_DMA_RX_BUF_SIZE);
	
    while(1)
    {
		if (rt_mq_recv(Uart1_Receive_mq, &data, sizeof(data), RT_WAITING_FOREVER) == RT_EOK)
		{
			Usart1_RxCallback(data.data,data.len);
			myfree(&mallco_dev,data.data);
		}
    }
}
/**********************
 * 功能：发送线程入口函数
***********************/
void Usart1_Send_thread_entry(void *paremeter)
{
	SerialData data;
	Usart1_send_mq=rt_mq_create("uart1_send_mq",      //消息队列名称
	                              sizeof(SerialData),                   //消息最大长度
	                              10,                   //队列长度
	                             RT_IPC_FLAG_FIFO      //等待的方式
	                             );
	Uart1_SendComplete_sem = rt_sem_create("Uart1_sendComplete", 0, RT_IPC_FLAG_PRIO);     //创建串口数据接收信号量
    while(1)
    {
		 if (rt_mq_recv(Usart1_send_mq, &data, sizeof(data), RT_WAITING_FOREVER) == RT_EOK)
		 {
			 USART1_DMASendData(&data);
			 rt_sem_take(Uart1_SendComplete_sem, 200);
			 myfree(&mallco_dev,data.data);
		 }
    }
}

/********************************
 * 功能：串口1DMA发送数据
 * 参数：
 *         *data:数据
 * 返回：无
********************************/
bool USART1_DMASendData(SerialData *data)
{
	  mymemcpy(UART1_DMA_TX_BUF,data->data,data->len);
    HAL_UART_Transmit_DMA(&huart1, UART1_DMA_TX_BUF, data->len);
}

/************************************
 *功能：串口接收中断回调函数
 *参数：
 *      huart:串口号
 *      size：数据长度
************************************/
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	SerialData serial_data;
	if(huart==&huart1)
	{
		if(huart->RxEventType == HAL_UART_RXEVENT_IDLE)
		{
			serial_data.data=(uint8_t *)mymalloc(&mallco_dev,Size);
			if(serial_data.data)
		  {
			 mymemcpy(serial_data.data,UART1_DMA_RX_BUF,Size);
			 serial_data.len=Size;
			 if(rt_mq_send(Uart1_Receive_mq, &serial_data, sizeof(SerialData))!=RT_EOK)
			 {
				myfree(&mallco_dev,serial_data.data);
			 }
		  }
		  HAL_UARTEx_ReceiveToIdle_DMA(huart,UART1_DMA_RX_BUF,UART1_DMA_RX_BUF_SIZE);
	  }
	}
}
/*******************************
 * 功能：串口发送完成回调函数
 * 参数：
 *         huart:串口句柄
 * 返回：
 * ****************************/
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart == &huart1)
    {
		rt_sem_release(Uart1_SendComplete_sem); //释放接收到数据信号量
    }
}

/************************************
*串口错误回调
************************************/
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
    if(huart == &huart1)
    {
		__HAL_UNLOCK(huart);
		HAL_UARTEx_ReceiveToIdle_DMA(huart,UART1_DMA_RX_BUF,UART1_DMA_RX_BUF_SIZE);
    }
}

/***********************************
*功能：串口3发送数据
*参数：
*				*buf：发送数据指针
*        len：数据长度
***********************************/
bool UART1SendData(uint8_t *data, uint8_t len)
{
	SerialData serial_data;
	serial_data.data = (uint8_t *)mymalloc(&mallco_dev, len);
	if(serial_data.data)
	{
		mymemcpy(serial_data.data,data,len);
		serial_data.len=len;
		if(rt_mq_send(Usart1_send_mq, &serial_data, sizeof(SerialData))!=RT_EOK)
		{
			myfree(&mallco_dev,serial_data.data);
			return false;
		}
		return true;
	}
	return false;
}

